home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libiconv_src.lha / src / hz.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-07  |  2.7 KB  |  142 lines

  1.  
  2. /*
  3.  * HZ
  4.  */
  5.  
  6. /* Specification: RFC 1842, RFC 1843 */
  7.  
  8. /*
  9.  * The state is 1 in GB mode, 0 in ASCII mode.
  10.  */
  11.  
  12. static int
  13. hz_mbtowc (conv_t conv, wchar_t *pwc, const unsigned char *s, int n)
  14. {
  15.   state_t state = conv->istate;
  16.   unsigned int count = 0;
  17.   unsigned char c;
  18.   for (;;) {
  19.     c = *s;
  20.     if (c == '~') {
  21.       if (n < count+2)
  22.         goto none;
  23.       c = s[1];
  24.       if (state == 0) {
  25.         if (c == '~') {
  26.           *pwc = (wchar_t) '~';
  27.           conv->istate = state;
  28.           return count+2;
  29.         }
  30.         if (c == '{') {
  31.           state = 1;
  32.           s += 2; count += 2;
  33.           if (n < count+1)
  34.             goto none;
  35.           continue;
  36.         }
  37.         if (c == '\n') {
  38.           s += 2; count += 2;
  39.           if (n < count+1)
  40.             goto none;
  41.           continue;
  42.         }
  43.       } else {
  44.         if (c == '}') {
  45.           state = 0;
  46.           s += 2; count += 2;
  47.           if (n < count+1)
  48.             goto none;
  49.           continue;
  50.         }
  51.       }
  52.       return RET_ILSEQ;
  53.     }
  54.     break;
  55.   }
  56.   if (state == 0) {
  57.     *pwc = (wchar_t) c;
  58.     conv->istate = state;
  59.     return count+1;
  60.   } else {
  61.     int ret;
  62.     if (n < count+2)
  63.       goto none;
  64.     ret = gb2312_mbtowc(conv,pwc,s,2);
  65.     if (ret == RET_ILSEQ)
  66.       return RET_ILSEQ;
  67.     if (ret != 2) abort();
  68.     conv->istate = state;
  69.     return count+2;
  70.   }
  71.  
  72. none:
  73.   conv->istate = state;
  74.   return RET_TOOFEW(count);
  75. }
  76.  
  77. static int
  78. hz_wctomb (conv_t conv, unsigned char *r, wchar_t wc, int n)
  79. {
  80.   state_t state = conv->ostate;
  81.   unsigned char buf[2];
  82.   int ret;
  83.  
  84.   /* Code set 0 (ASCII or GB 1988-89) */
  85.   ret = ascii_wctomb(conv,buf,wc,1);
  86.   if (ret != RET_ILSEQ) {
  87.     if (ret != 1) abort();
  88.     if (buf[0] < 0x80) {
  89.       int count = (state ? 3 : 1);
  90.       if (n < count)
  91.         return RET_TOOSMALL;
  92.       if (state) {
  93.         r[0] = '~';
  94.         r[1] = '}';
  95.         r += 2;
  96.         state = 0;
  97.       }
  98.       r[0] = buf[0];
  99.       conv->ostate = state;
  100.       return count;
  101.     }
  102.   }
  103.  
  104.   /* Code set 1 (GB 2312-1980) */
  105.   ret = gb2312_wctomb(conv,buf,wc,2);
  106.   if (ret != RET_ILSEQ) {
  107.     if (ret != 2) abort();
  108.     if (buf[0] < 0x80 && buf[1] < 0x80) {
  109.       int count = (state ? 2 : 4);
  110.       if (n < count)
  111.         return RET_TOOSMALL;
  112.       if (!state) {
  113.         r[0] = '~';
  114.         r[1] = '{';
  115.         r += 2;
  116.         state = 1;
  117.       }
  118.       r[0] = buf[0];
  119.       r[1] = buf[1];
  120.       conv->ostate = state;
  121.       return count;
  122.     }
  123.   }
  124.  
  125.   return RET_ILSEQ;
  126. }
  127.  
  128. static int
  129. hz_reset (conv_t conv, unsigned char *r, int n)
  130. {
  131.   state_t state = conv->ostate;
  132.   if (state) {
  133.     if (n < 2)
  134.       return RET_TOOSMALL;
  135.     r[0] = '~';
  136.     r[1] = '}';
  137.     /* conv->ostate = 0; will be done by the caller */
  138.     return 2;
  139.   } else
  140.     return 0;
  141. }
  142.